#!/usr/bin/python2

import sys

import pygame

from sprites import Door, Finish, Key, Level, Player, Speed, Spike, Wall
from utils import Constants, Patterns


class Map(object):

    @classmethod
    def get_map_info(cls):
        return ("WWW", "WPW", "WFW", "WWW")

    @classmethod
    def get_map_name(cls):
        return "Unnamed"

    @classmethod
    def load_map(cls):
        mainmenu = cls.get_map_name() == "Main Menu"
        selection = cls.get_map_name() == "Level Selection"
        fingrp = mainmenu or selection
        player = None
        groups = {"doors": pygame.sprite.Group(),
                  "finish": None if not fingrp else pygame.sprite.Group(),
                  "keys": pygame.sprite.Group(),
                  "speed": pygame.sprite.Group(),
                  "spikes": pygame.sprite.Group(),
                  "walls": pygame.sprite.Group()}
        if mainmenu:
            groups["__menu_title"] = (0, 0)
            groups["__menu_controls"] = (0, 0)
            groups["__menu_objective"] = (0, 0)
            groups["__menu_credits"] = (0, 0)
        info = cls.get_map_info()
        slots = Constants.SIZE // Constants.GRID_SIZE
        sym = (")", "!", "@", "#", "$", "%", "^", "&", "*", "(")
        for r in xrange(min(len(info), slots)):
            for c in xrange(min(len(info[r]), slots)):
                s = info[r][c]
                if s == "W":
                    Wall(c * Constants.GRID_SIZE, r * Constants.GRID_SIZE,
                         groups=groups["walls"])
                if s == "S":
                    Spike(c * Constants.GRID_SIZE, r * Constants.GRID_SIZE,
                          groups=groups["spikes"], rot=0)
                elif s == "Z":
                    Spike(c * Constants.GRID_SIZE, r * Constants.GRID_SIZE,
                          groups=groups["spikes"], rot=90)
                elif s == "s":
                    Spike(c * Constants.GRID_SIZE, r * Constants.GRID_SIZE,
                          groups=groups["spikes"], rot=180)
                elif s == "z":
                    Spike(c * Constants.GRID_SIZE, r * Constants.GRID_SIZE,
                          groups=groups["spikes"], rot=270)
                elif s == "P":
                    off = (Constants.GRID_SIZE - Constants.PLAYER_SIZE) // 2
                    player = Player(c * Constants.GRID_SIZE + off,
                                    r * Constants.GRID_SIZE + off)
                elif s == "F":
                    groups["finish"] = Finish(c * Constants.GRID_SIZE,
                                              r * Constants.GRID_SIZE).group()
                elif s == "G":
                    Speed(c * Constants.GRID_SIZE, r * Constants.GRID_SIZE,
                          Patterns.GLUE, 0.5, groups=groups["speed"])
                elif s == "R":
                    Speed(c * Constants.GRID_SIZE, r * Constants.GRID_SIZE,
                          Patterns.RAPID, 2.0, groups=groups["speed"])
                elif selection:
                    if s in (str(x) for x in xrange(10)):
                        cmap = None
                        nmap = "map%s" % s
                        d = sys.modules[__name__].__dict__
                        if nmap in d:
                            if nmap.title() in d[nmap].__dict__:
                                cmap = d[nmap].__dict__[nmap.title()]
                        if cmap:
                            p = Level(c * Constants.GRID_SIZE,
                                      r * Constants.GRID_SIZE,
                                      cmap, "%s" % s, groups=groups["finish"])
                            groups["_menu_lvl%s" % s] = p
                    elif s == "`":
                        e = Level(c * Constants.GRID_SIZE,
                                  r * Constants.GRID_SIZE,
                                  None, "EXIT", groups=groups["finish"])
                        groups["_menu_exit"] = e
                    elif s == "<":
                        e = Level(c * Constants.GRID_SIZE,
                                  r * Constants.GRID_SIZE,
                                  menu.Menu, "Menu", groups=groups["finish"])
                        groups["_menu_menu"] = e
                elif s in (str(x) for x in xrange(10)):
                    if not "_door%s" % s in groups:
                        groups["_door%s" % s] = pygame.sprite.Group()
                    patt = ("", )
                    if "DOOR%s" % s in Patterns.__dict__:
                        patt = Patterns.__dict__["DOOR%s" % s]
                    Door(c * Constants.GRID_SIZE, r * Constants.GRID_SIZE,
                         patt, groups=(groups["doors"], groups["_door%s" % s]))
                elif s in sym:
                    s = sym.index(s)
                    patt = ("", )
                    if "KEY%s" % s in Patterns.__dict__:
                        patt = Patterns.__dict__["KEY%s" % s]
                    off = (Constants.GRID_SIZE - Constants.KEY_SIZE) // 2
                    Key(c * Constants.GRID_SIZE + off,
                        r * Constants.GRID_SIZE + off, s, patt,
                        groups=groups["keys"])
                elif mainmenu:
                    if s == "~":
                        p = Level(c * Constants.GRID_SIZE,
                                  r * Constants.GRID_SIZE,
                                  map1.Map1, "PLAY", groups=groups["finish"])
                        groups["_menu_play"] = p
                    elif s == "`":
                        e = Level(c * Constants.GRID_SIZE,
                                  r * Constants.GRID_SIZE,
                                  None, "EXIT", groups=groups["finish"])
                        groups["_menu_exit"] = e
                    elif s == "?":
                        p = Level(c * Constants.GRID_SIZE,
                                  r * Constants.GRID_SIZE,
                                  levelsel.LevelSelect, "SELECT",
                                  groups=groups["finish"])
                        groups["_menu_choose"] = p
                    elif s == "|":
                        t = Level(c * Constants.GRID_SIZE,
                                  r * Constants.GRID_SIZE, menu.Menu,
                                  "SETTINGS", groups=groups["finish"])
                        groups["_menu_settings"] = t
                    elif s == "+":
                        groups["__menu_title"] = (c * Constants.GRID_SIZE,
                                                  r * Constants.GRID_SIZE)
                    elif s == "-":
                        groups["__menu_objective"] = (c * Constants.GRID_SIZE,
                                                      r * Constants.GRID_SIZE)
                    elif s == "_":
                        groups["__menu_credits"] = (c * Constants.GRID_SIZE,
                                                    r * Constants.GRID_SIZE)
                    elif s == "=":
                        groups["__menu_controls"] = (c * Constants.GRID_SIZE,
                                                     r * Constants.GRID_SIZE)
                    elif s == "M":
                        m = Level(c * Constants.GRID_SIZE,
                                  r * Constants.GRID_SIZE,
                                  "mute", "MUTE", groups=groups["finish"])
                        groups["_menu_mute"] = m
                    elif s == "U":
                        m = Level(c * Constants.GRID_SIZE,
                                  r * Constants.GRID_SIZE,
                                  "unmute", "UNMUTE", groups=groups["finish"])
                        groups["_menu_unmute"] = m
        return (player, groups)


import menu
import levelsel
import map1
import map2
import map3
import map4
import map5
# import map6
